package org.xmx0632.connector.handlers;

import java.net.SocketAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.xmx0632.connector.model.Gateway;
import org.xmx0632.connector.protocol.message.BaseMessage;
import org.xmx0632.connector.util.GlobalGateway;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * 调用远程接口,校验数据包合法性
 * 
 * 1.记录客户端连接/断开信息
 * 
 * 2.校验设备号(网关号)合法性
 * 
 * 3.设备白名单?
 * 
 * 4.设备黑名单?
 * 
 */
@Component
@Sharable
public class PreMessageProcessHandler extends SimpleChannelInboundHandler<BaseMessage> {

	private static final Logger LOG = LoggerFactory.getLogger(PreMessageProcessHandler.class);

//	@Autowired(required = false)
//	private IObjectRPC iObjectRPC;

	// 所有客户端连接
	public static ChannelGroup allClientChannels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

	// 记录客户端连接信息
	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		Channel incoming = ctx.channel();
		SocketAddress remoteAddress = incoming.remoteAddress();
		LOG.debug("client: {} connected.", remoteAddress);
		allClientChannels.add(ctx.channel());

		GlobalGateway.connect(remoteAddress.toString(), new Gateway(incoming));
	}

	// 记录客户端断开信息
	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		// A closed Channel is automatically removed from ChannelGroup,
		// so there is no need to do "allClientChannels.remove(ctx.channel());"
		Channel incoming = ctx.channel();
		LOG.debug("client: {} disconnect.", incoming.remoteAddress());
		GlobalGateway.disconnectByRemoteAddress(incoming.remoteAddress().toString());
	}

	@Override
	public void channelRead0(ChannelHandlerContext ctx, BaseMessage msg) throws Exception {
		LOG.debug("message name:{}", msg.getClass().getSimpleName());

		if (isValidMessage(msg)) {
			// 触发下一个handler
			ctx.fireChannelRead(msg);
		} else {
			disconnectClient(ctx, msg);
		}
	}

	// TODO 非法数据包,断开连接?
	private void disconnectClient(ChannelHandlerContext ctx, BaseMessage msg) {
		Channel incoming = ctx.channel();
		LOG.warn("invalid message:{} from:{}! disconnect now.", msg, incoming.remoteAddress());
		incoming.close();
	}

	// TODO 校验数据包合法性(设备记录是否存在)
	private boolean isValidMessage(BaseMessage msg) {
//		if (iObjectRPC == null) {
//			LOG.debug("RPC service not available,return true");
//			return true;
//		}
		// TODO 调用中科惠软[远程接口]?
		return true;
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		LOG.info("channelReadComplete");
		ctx.flush();
	}
}
